package FileIO;



import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;

import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;

import com.sun.xml.internal.bind.marshaller.XMLWriter;

import Entities.Diet;
import Entities.LCAChain;
import Entities.Impact;
import Entities.Material;
import Entities.Process;

public class writeXML {

	XMLStreamWriter writer;
	
	public writeXML(){}
	
	// with static void or not
	
	public void write(Diet diet, String filename) throws Exception{
		try {
			FileOutputStream out = new FileOutputStream(filename);
			writeXML writer = new writeXML(out);
			writer.writeFoods(diet.getFoods());
			writer.close();
		
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	

	public writeXML(OutputStream out) throws Exception{
		writer = XMLOutputFactory.newInstance().createXMLStreamWriter(out, "UTF-8");
		writer.writeStartDocument();
		writer.writeStartElement("Diet");
	}
	

	private void attribute(String name, String val) throws XMLStreamException {
		// TODO Auto-generated method stub
		if(val != null){
			System.out.println("name :"+ name +" val :"+val);
			writer.writeAttribute(name, val);
		}else{
			System.out.println("name :"+ name +" val :"+ " ");
			writer.writeAttribute(name, "null");
		}
	}
	
	/**
	 * close the write
	 * @throws Exception 
	 */
	public void close() throws Exception{
		if(writer != null){
			writer.writeEndElement();
			writer.writeEndDocument();
			writer.close();
		}
	}
	
	public void writeFoods(ArrayList<LCAChain> foods) throws Exception {
		// TODO Auto-generated method stub
		if(foods == null) return;
		for(LCAChain fs : foods){
			write(fs);
		}
	}
	
	public void write(LCAChain fs) throws Exception{
		writer.writeStartElement("Food");
		attribute("name",fs.getName());
		attribute("type",fs.getType());
		
		writeProcess(fs.getProcesses());
		
	}

	public void writeProcess(ArrayList<Process> processes) throws Exception {
		// TODO Auto-generated method stub
		if(processes == null) return;
		for(Process p : processes){
			writer.writeStartElement("Process");
			
			writeProcess(p);
			
			writer.writeEndElement();

		}
	}
	
	public void writeProcess(Process p) throws Exception {
		// TODO Auto-generated method stub
		this.attribute("p_name", p.getType());
		this.attribute("time", ""+p.getDuration());
		this.attribute("info", p.getInfo());
		writeInput(p.getInput());
		writeOutput(p.getOuput());
		writeImpact(p.getImpact());
		
		
	}

	private void writeImpact(ArrayList<Impact> impacts) throws Exception {
		// TODO Auto-generated method stub
		if(impacts == null) return;
		for(Impact i : impacts){
			writer.writeStartElement("impact");
			writeImpact(i);
			writer.writeEndElement();

		}
	}

	private void writeImpact(Impact i) throws Exception {
		// TODO Auto-generated method stub
		writer.writeStartElement("Evimpact");
		this.attribute("name",i.getName());
		this.attribute("type", i.getType());
		this.attribute("quantity", i.getQuantity()+"");
		this.attribute("unit", i.getUnit());
		writer.writeEndElement();

	}

	private void writeOutput(ArrayList<Material> ouputs) throws Exception {
		// TODO Auto-generated method stub
		if(ouputs == null) return;
		writer.writeStartElement("output");
		for(Material m : ouputs){
			writeMaterial(m);
		}
		writer.writeEndElement();
	}

	private void writeMaterial(Material m) throws Exception {
		// TODO Auto-generated method stub
		if(m == null) return;
		writer.writeStartElement("impact");
		this.attribute("name", m.getName());
		this.attribute("quantity", m.getQuantity()+"");
		this.attribute("isAdded", m.getIsAdd()+"");
		this.attribute("unit", m.getUnit());
		writer.writeEndElement();
	}

	private void writeInput(ArrayList<Material> inputs) throws Exception {
		// TODO Auto-generated method stub
		if(inputs == null) return;
		writer.writeStartElement("input");
		for(Material m : inputs){
			writeMaterial(m);
		}
		writer.writeEndElement();
	}
	
	
}
